package main.flex.helper
{
	import flash.events.Event;
	import flash.events.NetStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.SyncEvent;
	import flash.media.Camera;
	import flash.media.Microphone;
	import flash.media.Video;
	import flash.net.NetStream;
	import flash.net.Responder;
	import flash.net.SharedObject;
	import flash.system.Security;
	import flash.system.SecurityPanel;
	import flash.text.StyleSheet;
	
	import main.flex.connectivity.NetConnectionClient;
	import main.flex.connectivity.NetConnectionManager;
	import main.flex.connectivity.notification.NetConnectionClientEvent;
	import main.flex.control.MainController;
	import main.flex.model.MainModel;
	import main.flex.view.VisioView;
	
	import mx.controls.TextArea;
	
	import org.servebox.foundry.model.ModelLocator;
	import org.servebox.foundry.observation.IObservable;
	import org.servebox.foundry.observation.Notification;
	import org.servebox.foundry.view.ViewHelper;

	public class VisioViewHelper extends ViewHelper
	{	
		private var nc				:	NetConnectionManager;
		
		private var nsOut			:	NetStream;
		private var nsPlayerOut		:	NetStream;
		private var nsIn1			:	NetStream;
		private var nsPlayerIn1		:	NetStream;
		private var nsIn2			:	NetStream;
		private var nsPlayerIn2		:	NetStream;
		private var nsIn3			:	NetStream;
		private var nsPlayerIn3		:	NetStream;
		
		public var so				:	SharedObject;
		private var selectedUser	:	Number=0;
		private var cam				:	Camera;
		
		private var videoOut		:	Video;
		private var videoIn1		:	Video;
		private var videoIn2		:	Video;
		private var videoIn3		:	Video;
		
        private var outStream		:	String;
        private var inStream1		:	String;
        private var inStream2		:	String;
        private var inStream3		:	String;
        
		private var mic				:	Microphone;
		
		private var uId				:	int;
		private var uName			:	String;
		
        private var responder		:	Responder;
        
    	public var usersConnected 	:	Array = new Array();
    	
    	public var currentPosition	:	String;
    	
		public function VisioViewHelper()
		{
			super();
		}
		
		override public function registerToModels() : void
		{
			ModelLocator.getInstance().getModel( MainController.MAIN_MODEL_ID ).registerObserver( this );
		}
		
		public function init() : void
		{
			getCurrentView().currentState="chatMode";
			nc = NetConnectionManager.getInstance();
			nc.addEventListener("onConnect", onConnect);
			nc.addEventListener("netStatus", onNCStatus);
			nc.client = NetConnectionClient.getInstance();
			nc.client.addEventListener( NetConnectionClient.ON_USER_ID, onUserID );
			nc.client.addEventListener("onReceiveChatMsg", onReceiveChatMsg);
			
			getCurrentView().sendButton.enabled = getCurrentView().chatInputText.enabled = false;
			
			var uId : int = getMainModel().user.user[0].userId;
			var uName : String = getMainModel().user.user[0].name;
			
			//nc.createNetConnection( "rtmp://192.168.1.4/viavie/espace" + getMainModel().user.user[0].espaceId , uId, uName );
			//nc.createNetConnection( "rtmp://mac-serv.univ-tln.fr/viavie/test/" , uId, uName );
			nc.createNetConnection( "rtmp://localhost/viavie/espace" + getMainModel().user.user[0].espaceId, uId, uName );
			
		}
		
		public function userLoggedNotification_Fired( o : IObservable, n :Notification ) : void
		{
			dispatchEvent( new Event("userLogged") );
			if(getMainModel().user.user[0].userId!=0 && getMainModel().user.user[0].userId!="0" && getMainModel().user.user[0].userId!="-1" && getMainModel().user.user[0].userId!=-1 ) init();
		}
		
		private function onConnect(event:NetStatusEvent):void
		{
			getCurrentView().chatMsgText.htmlText="<font size='20' family='Verdana'>Vous etes connecté...</font></br>";
			so = SharedObject.getRemote("userList", nc.uri, false);
			so.addEventListener(SyncEvent.SYNC, onSync);
			so.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSOSecurityErrorEvent);
			so.addEventListener(NetStatusEvent.NET_STATUS, onSONetStatus);
			so.client=this;
			so.connect(nc);
		}
		
		private function onNCStatus(event:NetStatusEvent):void
		{
			switch (event.info.code) {
               case "NetConnection.Connect.Success":
               		responder=new Responder(streamNow);
                   	nc.call ("streamSelect",responder);
					break;
			}
		}
		
        private function streamNow (streamSelect:String):void
        {
        	//trace(streamSelect);
            setCam ();
            setMic ();
            setVid ();
             currentPosition=streamSelect;
             switch (streamSelect)
             {
                   case "left" :
                        outStream="left";
                        inStream1="right";
                        inStream2="top";
                        inStream3="bottom";
                        break;
                   case "right" :
                        outStream="right";
                        inStream1="left";
                        inStream2="top";
                        inStream3="bottom";
                        break;
                   case "top" :
                        outStream="top";
                        inStream1="left";
                        inStream2="right";
                        inStream3="bottom";
                        break;
                   case "bottom" :
                        outStream="bottom";
                        inStream1="left";
                        inStream2="top";
                        inStream3="right";
                        break;
             }

             //Publish local video
            nsOut = new NetStream(nc);
            nsOut.attachAudio(mic);
            nsOut.attachCamera (cam);
            nsOut.publish ( outStream , "live");
            nsPlayerOut = new NetStream(nc);
			nsPlayerOut.play( outStream );
           	videoOut.attachNetStream(nsPlayerOut);
           	getCurrentView().vidOut.width=videoOut.width;
           	getCurrentView().vidOut.height=videoOut.height;
			
             //Play streamed video
            nsIn2 = new NetStream(nc);
            nsIn2.attachCamera( cam );
            nsPlayerIn2 = new NetStream( nc );
           	videoIn2.attachNetStream( nsPlayerIn2 );
			nsPlayerIn2.play( inStream1 );
			getCurrentView().vidRight.width=videoIn2.width;
           	getCurrentView().vidRight.height=videoIn2.height;
           	
            nsIn1 = new NetStream( nc );
           	nsIn1.attachCamera( cam );
            nsPlayerIn1 = new NetStream( nc );
           	videoIn1.attachNetStream( nsPlayerIn1 );
			nsPlayerIn1.play( inStream2 );
			getCurrentView().vidBottom.width=videoIn1.width;
           	getCurrentView().vidBottom.height=videoIn1.height;
            
            nsIn3 = new NetStream(nc);
           	nsIn3.attachCamera (cam);
            nsPlayerIn3 = new NetStream(nc);
           	videoIn3.attachNetStream(nsPlayerIn3);
			nsPlayerIn3.play( inStream3 );
			getCurrentView().vidLeft.width=videoIn3.width;
           	getCurrentView().vidLeft.height=videoIn3.height;
           	
        }
        
        private function setCam ():void
        {
             cam=Camera.getCamera();
             cam.setMode (160,120,18);
             cam.setQuality (0,80);
        }

        private function setMic ():void
        {
             mic = Microphone.getMicrophone();
             Security.showSettings(SecurityPanel.MICROPHONE);
             mic.rate=11;
             mic.setSilenceLevel (12,2000);
        }
        
        private function setVid() :void
        {
			videoOut = new Video(160,120);
            getCurrentView().vidOut.addChild(videoOut);
			videoIn1 = new Video(200,150);
            getCurrentView().vidRight.addChild(videoIn1);
			videoIn2 = new Video(200,160);
            getCurrentView().vidBottom.addChild(videoIn2);
			videoIn3 = new Video(200,160);
            getCurrentView().vidLeft.addChild(videoIn3);
        }
		
		private function onSync(e:SyncEvent):void
		{
			var usersArray : Array = new Array();
			for (var i:String in so.data){
				usersArray.push({label:so.data[i].userName, data:so.data[i], position:i});
				//trace(i + " : " + so.data[i].userName);
				if(currentPosition=="left"){
					for(var j : Number = 0 ;j<4;j++){
						if(usersArray[j]!=null && usersArray[j].position=="bottom") getCurrentView().webcam4.title=usersArray[j].label;
						if(usersArray[j]!=null && usersArray[j].position=="top") getCurrentView().webcam2.title=usersArray[j].label;
						if(usersArray[j]!=null && usersArray[j].position=="right") getCurrentView().webcam3.title=usersArray[j].label;
						if(usersArray[j]!=null && usersArray[j].position=="left") getCurrentView().webcam1.title=usersArray[j].label;
					}
				}else if(currentPosition=="right"){
					for(var k : Number = 0 ;k<4;k++){
						if(usersArray[k]!=null && usersArray[k].position=="bottom") getCurrentView().webcam4.title=usersArray[k].label;
						if(usersArray[k]!=null && usersArray[k].position=="top") getCurrentView().webcam2.title=usersArray[k].label;
						if(usersArray[k]!=null && usersArray[k].position=="right") getCurrentView().webcam1.title=usersArray[k].label;
						if(usersArray[k]!=null && usersArray[k].position=="left") getCurrentView().webcam3.title=usersArray[k].label;
					}
				}else if(currentPosition=="top"){
					for(var l : Number = 0 ;l<4;l++){
						if(usersArray[l]!=null && usersArray[l].position=="bottom") getCurrentView().webcam4.title=usersArray[l].label;
						if(usersArray[l]!=null && usersArray[l].position=="top") getCurrentView().webcam1.title=usersArray[l].label;
						if(usersArray[l]!=null && usersArray[l].position=="right") getCurrentView().webcam2.title=usersArray[l].label;
						if(usersArray[l]!=null && usersArray[l].position=="left") getCurrentView().webcam3.title=usersArray[l].label;
					}
				}else if(currentPosition=="bottom"){
					for(var m : Number = 0 ;m<4;m++){
						if(usersArray[m]!=null && usersArray[m].position=="bottom") getCurrentView().webcam1.title=usersArray[m].label;
						if(usersArray[m]!=null && usersArray[m].position=="top") getCurrentView().webcam2.title=usersArray[m].label;
						if(usersArray[m]!=null && usersArray[m].position=="right") getCurrentView().webcam4.title=usersArray[m].label;
						if(usersArray[m]!=null && usersArray[m].position=="left") getCurrentView().webcam3.title=usersArray[m].label;
					}
				}
			}
			//trace(usersArray.length);
 			if(usersArray.length==1){
				getCurrentView().webcam1.visible=true;
				getCurrentView().webcam3.visible=false;
				getCurrentView().webcam2.visible=false;
				getCurrentView().webcam4.visible=false;
			}
			if(usersArray.length==2){
				getCurrentView().webcam1.visible=true;
				getCurrentView().webcam3.visible=true;
				getCurrentView().webcam2.visible=false;
				getCurrentView().webcam4.visible=false;
			}
			if(usersArray.length==3){
				getCurrentView().webcam1.visible=true;
				getCurrentView().webcam3.visible=true;
				getCurrentView().webcam2.visible=true;
				getCurrentView().webcam4.visible=false;
			}
			if(usersArray.length==4){
				getCurrentView().webcam1.visible=true;
				getCurrentView().webcam3.visible=true;
				getCurrentView().webcam2.visible=true;
				getCurrentView().webcam4.visible=true;
			} 
		}
		
		private function onEnterPressed(e:Event):void
		{
			if(getCurrentView().chatInputText.text!=""){
				sendTheMessage();
			}
		}
		
		public function onSendButtonClicked():void
		{
			if(getCurrentView().chatInputText.text!=""){
				sendTheMessage();
			}
		}
		
		public function sendTheMessage():void
		{
						
			var msg : String = "<font size='20' color='#99DD00'>" + getMainModel().user.user[0].name + " dit : </font><font size='20' color='#000000'>" + getCurrentView().chatInputText.text + "</font>";
			
			nc.call("sendChatMessage", null, msg, selectedUser);
			getCurrentView().chatInputText.text="";
		}
		
		[Bindable("onUserId")]
		private function onUserID(e:Event):void
		{
			getCurrentView().sendButton.enabled = getCurrentView().chatInputText.enabled = true;
		}
		
		private function onReceiveChatMsg(e:NetConnectionClientEvent):void
		{
			var msg:String = e.infoObject.msg;
			getCurrentView().chatMsgText.htmlText += msg + "\n";
		}
		
		public function changeViewMode():void
		{
			if(getCurrentView().currentState==null){
				getCurrentView().currentState="chatMode";
			}else if(getCurrentView().currentState=="chatMode"){
				getCurrentView().currentState=null;
			}
		}
		
		private function onSONetStatus(event:NetStatusEvent):void
		{
			trace("OnSONetStatus" + event);
		}
		
		private function onSOSecurityErrorEvent(event:SecurityErrorEvent):void
		{
			trace("OnSOSecurityError" + event);
		}
		
		// Shortcuts
		/**
		* return a reference to MainModel
		*/
		
		protected function getMainModel() : MainModel
		{
			return MainModel ( ModelLocator.getInstance().getModel( MainController.MAIN_MODEL_ID ));
		}
		
		public function getCurrentView( ) : VisioView
		{
			return VisioView( getView() );
		}
	}
}